package org.example.domain.order.entity;

import com.alibaba.cola.domain.Entity;
import com.alibaba.cola.exception.Assert;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.apache.commons.collections4.CollectionUtils;
import org.example.common.util.SpringUtil;
import org.example.domain.common.base.BaseEntity;
import org.example.domain.common.base.PropertyLoader;
import org.example.domain.order.gateway.OrderGateway;
import org.example.domain.order.gateway.OrderItemGateway;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * doNotUseGetters = true 目的是防止调用 toString 方法时，触发懒加载。
 * 例如在 IDEA 中进行 debug 时使用Evaluate Expression时，会自动调用toString，导致重复加载，影响调试
 */
@EqualsAndHashCode(callSuper = true)
@Data
@Entity
@ToString(doNotUseGetters = true)
public class OrderEntity extends BaseEntity<Long> {

    /**
     * 主键
     */
    private Long id;

    /**
     * 用户id
     */
    private Long userId;

    /**
     * 订单号
     */
    private String orderNo;

    /**
     * 实际支付金额(单位：分)
     */
    private Long payAmount;

    /**
     * 订单商品列表
     */
    private List<OrderItemEntity> orderItemList;

    private transient OrderItemGateway orderItemGateway = SpringUtil.getBean(OrderItemGateway.class);

    @Resource
    private OrderGateway orderGateway;

    public List<OrderItemEntity> getOrderItemList() {
        if (CollectionUtils.isEmpty(orderItemList)) {
            return lazyLoad("orderItemList", new PropertyLoader<List<OrderItemEntity>>() {
                @Override
                public void load() {
                    orderItemList = orderItemGateway.listByOrderNo(orderNo);
                }

                @Override
                public List<OrderItemEntity> get() {
                    return orderItemList;
                }
            });
        }
        return orderItemList;
    }

    @Override
    public Long getPrimaryId() {
        return id;
    }

    @Override
    public void setPrimaryId(Long id) {
        this.id = id;
    }

    /**
     * 校验订单金额
     */
    public void validatePayAmount() {
        if (CollectionUtils.isNotEmpty(orderItemList)) {
            long shouldAmount = orderItemList.stream()
                    .mapToLong(item -> Math.multiplyExact(item.getItemPrice(), item.getQuantity()))
                    .sum();
            Assert.isTrue(Objects.equals(shouldAmount, payAmount), "订单金额不正确");
        } else {
            Assert.isTrue(Objects.equals(0L, payAmount), "订单金额不正确");
        }
    }

    /**
     * 生成订单号
     */
    public void generateOrderNo() {
        this.orderNo = UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 将订单号组装到订单商品中
     */
    public void setOrderItemListOrderNo() {
        if (CollectionUtils.isNotEmpty(orderItemList)) {
            orderItemList.forEach(item -> item.setOrderNo(orderNo));
        }
    }

    /**
     * 将订单 id 组装到订单商品中
     */
    public void setOrderItemListOrderId(Long orderId) {
        if (CollectionUtils.isNotEmpty(orderItemList)) {
            orderItemList.forEach(item -> item.setOrderId(orderId));
        }
    }
}
